﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Xin478.CSWork.Common;

namespace Xin478.CSWork.Client
{
    public class RemindHelper
    {
        public static readonly RemindHelper Instance = new RemindHelper();

        readonly static object lockHelper = new object();
        int maxLiftTime=3600;
        const int REPEATINTERVAL = 1000;
        DateTime beginTime;
        SortedDictionary<long, RemindInfo> list = new SortedDictionary<long, RemindInfo>();

        System.Timers.Timer timer;

        public event EventHandler RemindTrigger;
        public event EventHandler Elapsed;

        private RemindHelper() {}

        public void Add(IList<RemindInfo> ris)
        {
            if(ris!=null)
                foreach (RemindInfo ri in ris) 
                    this.Add(ri);
        }

        public void Add(RemindInfo ri)
        {
            if (ri == null ) return;
            DateTime dt;
            DateTime now = DateTime.Now;
            if (ri.DefiniteDate == null)
            {
                if (ri.PlanType > 0)
                {
                    if (ri.PlanType != now.Day) return;
                }
                else if (ri.PlanType < 0)
                {
                    if (ri.PlanType != -(int)(Enum.Parse(typeof(DayOfWeek), now.DayOfWeek.ToString()))) return;
                }
                dt = new DateTime(now.Year,now.Month,now.Day);
            }
            else
            {
                dt = DateTime.Parse(ri.DefiniteDate);
            }

            if (ri.DefiniteTime > 0)
            {
                dt = dt.AddMinutes(ri.DefiniteTime % 100).AddHours((int)(ri.DefiniteTime / 100));
            }
            else dt = dt.AddSeconds(now.Second).AddMilliseconds(now.Millisecond);

            if( dt<now && ri.DelayTime<=0 && !string.IsNullOrEmpty(ri.DefiniteDate)) return;

            long t = dt.Ticks;
            lock (lockHelper)
            {
                while (list.ContainsKey(t)) 
                    t += 10000000;
                list.Add(t, ri);
            }
        }

        public void Clear()
        {
            lock (lockHelper)
            {
                if (timer != null) timer.Stop();
                this.list.Clear();
            }
        }

        public void Remove(int rid)
        {
            lock (lockHelper)
            {
                if (list.Count == 0) return;
                SortedDictionary<long, RemindInfo>.Enumerator enumerator = list.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    if (enumerator.Current.Value.Id == rid)
                    {
                        list.Remove(enumerator.Current.Key);
                        if (timer != null)
                        {
                            timer.Stop();
                            timer = null;
                        }
                        break;
                    }
                }

            }
            Start();
        }

        public void Remove(RemindInfo ri)
        {
            Remove(ri.Id);
        }

        public void Start()
        {
            if (list.Count == 0)
            { 
                timer = null; 
                return; 
            }

            if (timer != null) return;

            timer = new System.Timers.Timer();
            timer.AutoReset = false;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
                            
            SortedDictionary<long, RemindInfo>.Enumerator enumerator = list.GetEnumerator();

            if (enumerator.MoveNext())
            {
                long d = enumerator.Current.Key - DateTime.Now.Ticks;
                if (d > 0 && d < 10000) d = 10000;
                timer.Interval = d > 0 ? d / 10000 : REPEATINTERVAL;
            }
            else
                return;

            timer.Start();
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            RemindInfo ri=null;
            long d;
            lock (lockHelper)
            {
                SortedDictionary<long, RemindInfo>.Enumerator enumerator = list.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    d = enumerator.Current.Key - DateTime.Now.Ticks;
                    if (d > 0 && d < 10000) d = 10000;
                    if (d>0)
                    {
                        timer.Interval = d / 10000 ;
                        timer.Start();
                    }
                    else
                    {
                        ri = enumerator.Current.Value;
                        long i = enumerator.Current.Key;
                        list.Remove(i);

                        if (ri.Interval > 0)
                        {
                            i = DateTime.Now.AddMinutes(ri.Interval).Ticks;
                            while (list.ContainsKey(i)) i+=100;
                            list.Add(i , ri);
                        }

                        enumerator = list.GetEnumerator();
                        if (enumerator.MoveNext())
                        {
                            d = enumerator.Current.Key - DateTime.Now.Ticks;
                            if (d > 0 && d < 10000) d = 10000;
                            timer.Interval = d > 0 ? d / 10000 : REPEATINTERVAL;
                            timer.Start();
                        }
                        else
                        {
                            timer.Stop();
                            timer.Dispose();
                            timer = null;
                        }

                    }
                }
                else
                {
                    timer.Stop();
                    timer.Dispose();
                    timer = null;
                }
            }
            
            if (ri!=null && RemindTrigger != null) RemindTrigger(ri, e);
            
        }
    }
    
}
